// Copyright 2013 The Flutter Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

void main() => runApp(App());

/// The main app.
class App extends StatelessWidget {
  /// Creates an [App].
  App({super.key});

  /// The title of the app.
  static const String title = 'GoRouter Example: Custom Transitions';

  @override
  Widget build(BuildContext context) =>
      MaterialApp.router(routerConfig: _router, title: title);

  final GoRouter _router = GoRouter(
    routes: <GoRoute>[
      GoRoute(path: '/', redirect: (_, __) => '/none'),
      GoRoute(
        path: '/fade',
        pageBuilder: (BuildContext context, GoRouterState state) =>
            CustomTransitionPage<void>(
              key: state.pageKey,
              child: const ExampleTransitionsScreen(
                kind: 'fade',
                color: Colors.red,
              ),
              transitionsBuilder:
                  (
                    BuildContext context,
                    Animation<double> animation,
                    Animation<double> secondaryAnimation,
                    Widget child,
                  ) => FadeTransition(opacity: animation, child: child),
            ),
      ),
      GoRoute(
        path: '/scale',
        pageBuilder: (BuildContext context, GoRouterState state) =>
            CustomTransitionPage<void>(
              key: state.pageKey,
              child: const ExampleTransitionsScreen(
                kind: 'scale',
                color: Colors.green,
              ),
              transitionsBuilder:
                  (
                    BuildContext context,
                    Animation<double> animation,
                    Animation<double> secondaryAnimation,
                    Widget child,
                  ) => ScaleTransition(scale: animation, child: child),
            ),
      ),
      GoRoute(
        path: '/slide',
        pageBuilder: (BuildContext context, GoRouterState state) =>
            CustomTransitionPage<void>(
              key: state.pageKey,
              child: const ExampleTransitionsScreen(
                kind: 'slide',
                color: Colors.yellow,
              ),
              transitionsBuilder:
                  (
                    BuildContext context,
                    Animation<double> animation,
                    Animation<double> secondaryAnimation,
                    Widget child,
                  ) => SlideTransition(
                    position: animation.drive(
                      Tween<Offset>(
                        begin: const Offset(0.25, 0.25),
                        end: Offset.zero,
                      ).chain(CurveTween(curve: Curves.easeIn)),
                    ),
                    child: child,
                  ),
            ),
      ),
      GoRoute(
        path: '/rotation',
        pageBuilder: (BuildContext context, GoRouterState state) =>
            CustomTransitionPage<void>(
              key: state.pageKey,
              child: const ExampleTransitionsScreen(
                kind: 'rotation',
                color: Colors.purple,
              ),
              transitionsBuilder:
                  (
                    BuildContext context,
                    Animation<double> animation,
                    Animation<double> secondaryAnimation,
                    Widget child,
                  ) => RotationTransition(turns: animation, child: child),
            ),
      ),
      GoRoute(
        path: '/none',
        pageBuilder: (BuildContext context, GoRouterState state) =>
            NoTransitionPage<void>(
              key: state.pageKey,
              child: const ExampleTransitionsScreen(
                kind: 'none',
                color: Colors.white,
              ),
            ),
      ),
    ],
  );
}

/// An Example transitions screen.
class ExampleTransitionsScreen extends StatelessWidget {
  /// Creates an [ExampleTransitionsScreen].
  const ExampleTransitionsScreen({
    required this.color,
    required this.kind,
    super.key,
  });

  /// The available transition kinds.
  static final List<String> kinds = <String>[
    'fade',
    'scale',
    'slide',
    'rotation',
    'none',
  ];

  /// The color of the container.
  final Color color;

  /// The transition kind.
  final String kind;

  @override
  Widget build(BuildContext context) => Scaffold(
    appBar: AppBar(title: Text('${App.title}: $kind')),
    body: ColoredBox(
      color: color,
      child: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            for (final String kind in kinds)
              Padding(
                padding: const EdgeInsets.all(8),
                child: ElevatedButton(
                  onPressed: () => context.go('/$kind'),
                  child: Text('$kind transition'),
                ),
              ),
          ],
        ),
      ),
    ),
  );
}
